use std::sync::{Arc, Mutex as StdMutex};
use tokio::sync::Mutex;
use anyhow::{Result, anyhow};
use uuid::Uuid;
use std::collections::HashMap;
use log::{info, error, debug, warn};
use ssh2::{Session, Channel};
use std::io::{Read, Write};
use tokio::sync::mpsc;
use serde::{Serialize, Deserialize};

/// 终端大小
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct TerminalSize {
    pub cols: u32,
    pub rows: u32,
    pub width_px: u32,
    pub height_px: u32,
}

impl Default for TerminalSize {
    fn default() -> Self {
        Self {
            cols: 80,
            rows: 24,
            width_px: 640,
            height_px: 480,
        }
    }
}

/// 终端事件
#[derive(Debug, Clone)]
pub enum TerminalEvent {
    /// 输入数据
    Input(Vec<u8>),
    /// 输出数据
    Output(Vec<u8>),
    /// 调整大小
    Resize(TerminalSize),
    /// 连接状态变化
    ConnectionChanged(bool),
    /// 错误事件
    Error(String),
    /// 终端关闭
    Closed,
}

/// 终端状态
#[derive(Debug, Clone, PartialEq)]
pub enum TerminalStatus {
    Disconnected,
    Connecting,
    Connected,
    Error(String),
    Closed,
}

/// 终端配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TerminalConfig {
    pub id: String,
    pub name: String,
    pub connection_id: String,
    pub size: TerminalSize,
    pub shell: Option<String>,
    pub env_vars: HashMap<String, String>,
    pub working_directory: Option<String>,
}

impl TerminalConfig {
    pub fn new(name: String, connection_id: String) -> Self {
        Self {
            id: Uuid::new_v4().to_string(),
            name,
            connection_id,
            size: TerminalSize::default(),
            shell: None,
            env_vars: HashMap::new(),
            working_directory: None,
        }
    }

    pub fn with_size(mut self, size: TerminalSize) -> Self {
        self.size = size;
        self
    }

    pub fn with_shell(mut self, shell: String) -> Self {
        self.shell = Some(shell);
        self
    }

    pub fn with_env_var(mut self, key: String, value: String) -> Self {
        self.env_vars.insert(key, value);
        self
    }

    pub fn with_working_directory(mut self, dir: String) -> Self {
        self.working_directory = Some(dir);
        self
    }
}

/// 终端实例
pub struct Terminal {
    pub config: TerminalConfig,
    pub status: Arc<Mutex<TerminalStatus>>,
    channel: Option<Arc<StdMutex<Channel>>>,
    event_sender: Option<mpsc::UnboundedSender<TerminalEvent>>,
    event_receiver: Option<mpsc::UnboundedReceiver<TerminalEvent>>,
    input_buffer: Arc<Mutex<Vec<u8>>>,
    output_buffer: Arc<Mutex<Vec<u8>>>,
}

impl Terminal {
    pub fn new(config: TerminalConfig) -> Self {
        let (event_sender, event_receiver) = mpsc::unbounded_channel();
        
        Self {
            config,
            status: Arc::new(Mutex::new(TerminalStatus::Disconnected)),
            channel: None,
            event_sender: Some(event_sender),
            event_receiver: Some(event_receiver),
            input_buffer: Arc::new(Mutex::new(Vec::new())),
            output_buffer: Arc::new(Mutex::new(Vec::new())),
        }
    }

    /// 连接到SSH会话
    pub async fn connect(&mut self, ssh_session: Arc<Mutex<Session>>) -> Result<()> {
        info!("连接终端: {} ({})", self.config.name, self.config.id);
        
        {
            let mut status = self.status.lock().await;
            *status = TerminalStatus::Connecting;
        }

        // 在阻塞任务中创建SSH通道
        let session = Arc::clone(&ssh_session);
        let size = self.config.size;
        let shell = self.config.shell.clone();
        let env_vars = self.config.env_vars.clone();
        let working_dir = self.config.working_directory.clone();
        
        let channel = tokio::task::spawn_blocking(move || -> Result<Channel> {
            // 在阻塞任务内部获取会话锁
            let session_guard = futures::executor::block_on(session.lock());
            
            // 创建通道
            let mut channel = session_guard.channel_session()
                .map_err(|e| anyhow!("创建SSH通道失败: {}", e))?;
            
            // 请求PTY
            channel.request_pty(
                "xterm-256color",
                None,
                Some((size.cols, size.rows, size.width_px, size.height_px))
            ).map_err(|e| anyhow!("请求PTY失败: {}", e))?;
            
            // 设置环境变量
            for (key, value) in env_vars {
                if let Err(e) = channel.setenv(&key, &value) {
                    warn!("设置环境变量失败 {}={}: {}", key, value, e);
                }
            }
            
            // 启动shell或执行命令
            if let Some(shell_cmd) = shell {
                channel.exec(&shell_cmd)
                    .map_err(|e| anyhow!("执行shell命令失败: {}", e))?;
            } else {
                channel.shell()
                    .map_err(|e| anyhow!("启动shell失败: {}", e))?;
            }
            
            // 如果指定了工作目录，发送cd命令
            if let Some(dir) = working_dir {
                let cd_cmd = format!("cd {}\n", dir);
                channel.write_all(cd_cmd.as_bytes())
                    .map_err(|e| anyhow!("设置工作目录失败: {}", e))?;
            }
            
            Ok(channel)
        }).await.map_err(|e| anyhow!("创建终端通道任务失败: {}", e))??;
        
        self.channel = Some(Arc::new(StdMutex::new(channel)));
        
        {
            let mut status = self.status.lock().await;
            *status = TerminalStatus::Connected;
        }
        
        // 启动数据处理任务
        self.start_data_processing().await?;
        
        // 发送连接事件
        if let Some(sender) = &self.event_sender {
            let _ = sender.send(TerminalEvent::ConnectionChanged(true));
        }
        
        info!("终端连接成功: {}", self.config.name);
        Ok(())
    }

    /// 启动数据处理任务
    async fn start_data_processing(&mut self) -> Result<()> {
        let channel = self.channel.as_ref()
            .ok_or_else(|| anyhow!("终端通道未初始化"))?;
        
        let channel_clone = Arc::clone(channel);
        let event_sender = self.event_sender.as_ref()
            .ok_or_else(|| anyhow!("事件发送器未初始化"))?
            .clone();
        let output_buffer = Arc::clone(&self.output_buffer);
        
        // 启动输出读取任务
        tokio::spawn(async move {
            let mut buffer = [0u8; 4096];
            
            loop {
                let result = tokio::task::spawn_blocking({
                    let channel = Arc::clone(&channel_clone);
                    move || {
                        // 直接使用阻塞锁，避免锁竞争
                        
                        // 使用阻塞锁，但快速释放
                        match channel.lock() {
                            Ok(mut channel_guard) => {
                                // 成功获取锁，进行读取操作
                                match channel_guard.read(&mut buffer) {
                                    Ok(n) => return Ok(n),
                                    Err(e) => {
                                        // 检查是否是暂时无数据的错误
                                        if e.kind() == std::io::ErrorKind::WouldBlock {
                                            return Ok(0); // 暂时无数据
                                        } else {
                                            return Err(e); // 真正的错误
                                        }
                                    }
                                }
                            }
                            Err(e) => {
                                println!("[ERROR] 获取SSH通道锁失败: {}", e);
                                return Ok(0); // 返回0表示暂时无数据
                            }
                        }
                    }
                }).await;
                
                match result {
                    Ok(Ok(0)) => {
                        // 暂时无数据，短暂等待后继续
                        tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
                        continue;
                    }
                    Ok(Ok(n)) if n > 0 => {
                        let data = buffer[..n].to_vec();
                        println!("[DEBUG] 从SSH通道读取到数据: {} 字节", n);
                        println!("[DEBUG] 数据内容: {:?}", String::from_utf8_lossy(&data));
                        
                        // 添加到输出缓冲区
                        {
                            let mut output_buf = output_buffer.lock().await;
                            output_buf.extend_from_slice(&data);
                            
                            // 限制缓冲区大小
                            if output_buf.len() > 1024 * 1024 { // 1MB
                                let half_len = output_buf.len() / 2;
                                output_buf.drain(..half_len);
                            }
                        }
                        
                        // 发送输出事件
                        println!("[DEBUG] 发送终端输出事件到前端");
                        if let Err(e) = event_sender.send(TerminalEvent::Output(data)) {
                            error!("发送输出事件失败: {}", e);
                            break;
                        }
                    }
                    Ok(Ok(_)) => {
                        // 处理其他可能的返回值
                        debug!("终端读取返回未预期的值");
                    }
                    Ok(Err(e)) => {
                        error!("读取终端输出失败: {}", e);
                        let _ = event_sender.send(TerminalEvent::Error(format!("读取失败: {}", e)));
                        // 发生错误时等待一下再重试，避免快速循环
                        tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
                    }
                    Err(e) => {
                        error!("终端读取任务失败: {}", e);
                        break;
                    }
                }
            }
        });
        
        Ok(())
    }

    /// 发送输入数据
    pub async fn send_input(&self, data: &[u8]) -> Result<()> {
        println!("[DEBUG] Terminal::send_input 被调用:");
        println!("  data_len: {}", data.len());
        println!("  data_bytes: {:?}", data);
        println!("  data_str: {:?}", String::from_utf8_lossy(data));
        
        let channel = self.channel.as_ref()
            .ok_or_else(|| anyhow!("终端未连接"))?;
        
        println!("[DEBUG] 终端通道已获取，准备写入数据");
        
        // 添加到输入缓冲区
        {
            let mut input_buf = self.input_buffer.lock().await;
            input_buf.extend_from_slice(data);
            println!("[DEBUG] 数据已添加到输入缓冲区，缓冲区大小: {}", input_buf.len());
        }
        
        // 发送数据到SSH通道
        println!("[DEBUG] 开始向SSH通道写入数据");
        
        // 在阻塞任务中执行SSH操作，使用超时避免死锁
        let result = tokio::time::timeout(
            tokio::time::Duration::from_millis(1000), // 1秒超时
            tokio::task::spawn_blocking({
                let channel = Arc::clone(channel);
                let data = data.to_vec();
                move || {
                    println!("[DEBUG] 在阻塞任务中尝试获取SSH通道锁");
                    
                    // 使用try_lock避免长时间阻塞
                    let mut retry_count = 0;
                    let max_retries = 10;
                    
                    loop {
                        match channel.try_lock() {
                            Ok(mut channel_guard) => {
                                println!("[DEBUG] SSH通道锁已获取，开始写入数据");
                                
                                match channel_guard.write_all(&data) {
                                    Ok(()) => {
                                        println!("[DEBUG] 数据写入成功，开始刷新");
                                        match channel_guard.flush() {
                                            Ok(()) => {
                                                println!("[DEBUG] 数据刷新成功");
                                                return Ok(());
                                            }
                                            Err(e) => {
                                                println!("[ERROR] 数据刷新失败: {}", e);
                                                return Err(anyhow!("数据刷新失败: {}", e));
                                            }
                                        }
                                    }
                                    Err(e) => {
                                        println!("[ERROR] 数据写入失败: {}", e);
                                        return Err(anyhow!("数据写入失败: {}", e));
                                    }
                                }
                            }
                            Err(_) => {
                                retry_count += 1;
                                if retry_count >= max_retries {
                                    println!("[ERROR] SSH通道锁获取超时，重试次数已达上限");
                                    return Err(anyhow!("SSH通道锁获取超时"));
                                }
                                println!("[DEBUG] SSH通道锁被占用，等待重试 ({}/{})", retry_count, max_retries);
                                std::thread::sleep(std::time::Duration::from_millis(10));
                            }
                        }
                    }
                }
            })
        ).await;
        
        match result {
            Ok(Ok(Ok(()))) => {
                println!("[DEBUG] SSH通道写入和刷新成功");
            }
            Ok(Ok(Err(e))) => {
                println!("[ERROR] 写入终端失败: {}", e);
                return Err(e);
            }
            Ok(Err(e)) => {
                println!("[ERROR] 阻塞任务失败: {}", e);
                return Err(anyhow!("阻塞任务失败: {}", e));
            }
            Err(_) => {
                println!("[ERROR] SSH通道写入操作超时");
                return Err(anyhow!("SSH通道写入操作超时"));
            }
        }
        
        // 发送输入事件
        if let Some(sender) = &self.event_sender {
            println!("[DEBUG] 发送输入事件");
            let _ = sender.send(TerminalEvent::Input(data.to_vec()));
        } else {
            println!("[WARN] 事件发送器未初始化，无法发送输入事件");
        }
        
        println!("[DEBUG] Terminal::send_input 执行完成");
        Ok(())
    }

    /// 调整终端大小
    pub async fn resize(&mut self, size: TerminalSize) -> Result<()> {
        self.config.size = size;
        
        if let Some(channel) = &self.channel {
            let result = tokio::task::spawn_blocking({
            let channel = Arc::clone(channel);
            move || {
                let mut channel_guard = channel.lock().unwrap();
                channel_guard.request_pty_size(size.cols, size.rows, Some(size.width_px), Some(size.height_px))
            }
        }).await.map_err(|e| anyhow!("调整大小任务失败: {}", e))?;
        
        result.map_err(|e| anyhow!("调整终端大小失败: {}", e))?;
        }
        
        // 发送调整大小事件
        if let Some(sender) = &self.event_sender {
            let _ = sender.send(TerminalEvent::Resize(size));
        }
        
        info!("终端大小已调整: {}x{}", size.cols, size.rows);
        Ok(())
    }

    /// 获取终端状态
    pub async fn get_status(&self) -> TerminalStatus {
        let status = self.status.lock().await;
        status.clone()
    }

    /// 获取输出缓冲区内容
    pub async fn get_output_buffer(&self) -> Vec<u8> {
        let buffer = self.output_buffer.lock().await;
        buffer.clone()
    }

    /// 清空输出缓冲区
    pub async fn clear_output_buffer(&self) {
        let mut buffer = self.output_buffer.lock().await;
        buffer.clear();
    }

    /// 获取事件接收器
    pub fn take_event_receiver(&mut self) -> Option<mpsc::UnboundedReceiver<TerminalEvent>> {
        self.event_receiver.take()
    }

    /// 断开连接
    pub async fn disconnect(&mut self) -> Result<()> {
        info!("断开终端连接: {}", self.config.name);
        
        if let Some(channel) = &self.channel {
            tokio::task::spawn_blocking({
                let channel = Arc::clone(channel);
                move || {
                    let mut channel_guard = channel.lock().unwrap();
                    let _ = channel_guard.close();
                    let _ = channel_guard.wait_close();
                }
            }).await.map_err(|e| anyhow!("关闭通道任务失败: {}", e))?;
        }
        
        self.channel = None;
        
        {
            let mut status = self.status.lock().await;
            *status = TerminalStatus::Disconnected;
        }
        
        // 发送连接状态变化事件
        if let Some(sender) = &self.event_sender {
            let _ = sender.send(TerminalEvent::ConnectionChanged(false));
        }
        
        info!("终端连接已断开: {}", self.config.name);
        Ok(())
    }

    /// 执行命令
    pub async fn execute_command(&self, command: &str) -> Result<()> {
        let cmd_with_newline = format!("{}\n", command);
        self.send_input(cmd_with_newline.as_bytes()).await?;
        
        info!("执行命令: {}", command);
        Ok(())
    }

    /// 发送特殊键
    pub async fn send_key(&self, key: TerminalKey) -> Result<()> {
        let key_sequence = match key {
            TerminalKey::Enter => b"\r".to_vec(),
            TerminalKey::Tab => b"\t".to_vec(),
            TerminalKey::Backspace => b"\x7f".to_vec(),
            TerminalKey::Delete => b"\x1b[3~".to_vec(),
            TerminalKey::ArrowUp => b"\x1b[A".to_vec(),
            TerminalKey::ArrowDown => b"\x1b[B".to_vec(),
            TerminalKey::ArrowRight => b"\x1b[C".to_vec(),
            TerminalKey::ArrowLeft => b"\x1b[D".to_vec(),
            TerminalKey::Home => b"\x1b[H".to_vec(),
            TerminalKey::End => b"\x1b[F".to_vec(),
            TerminalKey::PageUp => b"\x1b[5~".to_vec(),
            TerminalKey::PageDown => b"\x1b[6~".to_vec(),
            TerminalKey::Escape => b"\x1b".to_vec(),
            TerminalKey::CtrlC => b"\x03".to_vec(),
            TerminalKey::CtrlD => b"\x04".to_vec(),
            TerminalKey::CtrlZ => b"\x1a".to_vec(),
        };
        
        self.send_input(&key_sequence).await
    }
}

/// 终端特殊键
#[derive(Debug, Clone, Copy)]
pub enum TerminalKey {
    Enter,
    Tab,
    Backspace,
    Delete,
    ArrowUp,
    ArrowDown,
    ArrowRight,
    ArrowLeft,
    Home,
    End,
    PageUp,
    PageDown,
    Escape,
    CtrlC,
    CtrlD,
    CtrlZ,
}

/// 终端管理器
#[derive(Clone)]
pub struct TerminalManager {
    terminals: Arc<Mutex<HashMap<String, Terminal>>>,
}

impl TerminalManager {
    pub fn new() -> Self {
        Self {
            terminals: Arc::new(Mutex::new(HashMap::new())),
        }
    }

    /// 创建终端
    pub async fn create_terminal(&self, config: TerminalConfig) -> Result<String> {
        let terminal_id = config.id.clone();
        let terminal = Terminal::new(config);
        
        {
            let mut terminals = self.terminals.lock().await;
            terminals.insert(terminal_id.clone(), terminal);
        }
        
        info!("创建终端成功: {}", terminal_id);
        Ok(terminal_id)
    }

    /// 连接终端
    pub async fn connect_terminal(
        &self,
        terminal_id: &str,
        ssh_session: Arc<Mutex<Session>>,
    ) -> Result<()> {
        let mut terminals = self.terminals.lock().await;
        let terminal = terminals.get_mut(terminal_id)
            .ok_or_else(|| anyhow!("终端不存在: {}", terminal_id))?;
        
        terminal.connect(ssh_session).await
    }

    /// 发送输入到终端
    pub async fn send_input(&self, terminal_id: &str, data: &[u8]) -> Result<()> {
        println!("[DEBUG] TerminalManager::send_input 被调用: terminal_id={}, data={:?}", terminal_id, String::from_utf8_lossy(data));
        
        // 获取终端实例的引用
        let terminals = self.terminals.lock().await;
        if let Some(terminal) = terminals.get(terminal_id) {
            println!("[DEBUG] 找到终端实例，调用 terminal.send_input");
            // 直接调用，不需要克隆
            terminal.send_input(data).await
        } else {
            println!("[DEBUG] 未找到终端实例: {}", terminal_id);
            Err(anyhow!("终端不存在: {}", terminal_id))
        }
    }

    /// 调整终端大小
    pub async fn resize_terminal(&self, terminal_id: &str, size: TerminalSize) -> Result<()> {
        let mut terminals = self.terminals.lock().await;
        let terminal = terminals.get_mut(terminal_id)
            .ok_or_else(|| anyhow!("终端不存在: {}", terminal_id))?;
        
        terminal.resize(size).await
    }

    /// 断开终端连接
    pub async fn disconnect_terminal(&self, terminal_id: &str) -> Result<()> {
        let mut terminals = self.terminals.lock().await;
        let terminal = terminals.get_mut(terminal_id)
            .ok_or_else(|| anyhow!("终端不存在: {}", terminal_id))?;
        
        terminal.disconnect().await
    }

    /// 删除终端
    pub async fn remove_terminal(&self, terminal_id: &str) -> Result<()> {
        let mut terminals = self.terminals.lock().await;
        if let Some(mut terminal) = terminals.remove(terminal_id) {
            terminal.disconnect().await?;
        }
        
        info!("删除终端: {}", terminal_id);
        Ok(())
    }

    /// 获取所有终端状态
    pub async fn get_all_terminals(&self) -> Vec<(String, TerminalConfig, TerminalStatus)> {
        let terminals = self.terminals.lock().await;
        let mut result = Vec::new();
        
        for (id, terminal) in terminals.iter() {
            let status = terminal.get_status().await;
            result.push((id.clone(), terminal.config.clone(), status));
        }
        
        result
    }

    /// 获取终端事件接收器
    pub async fn get_terminal_events(&self, terminal_id: &str) -> Result<mpsc::UnboundedReceiver<TerminalEvent>> {
        let mut terminals = self.terminals.lock().await;
        let terminal = terminals.get_mut(terminal_id)
            .ok_or_else(|| anyhow!("终端不存在: {}", terminal_id))?;
        
        terminal.take_event_receiver()
            .ok_or_else(|| anyhow!("事件接收器已被获取"))
    }
}

impl Default for TerminalManager {
    fn default() -> Self {
        Self::new()
    }
}

/// 便捷函数：创建终端配置
pub fn create_terminal_config(
    name: String,
    connection_id: String,
    cols: u32,
    rows: u32,
) -> TerminalConfig {
    TerminalConfig::new(name, connection_id)
        .with_size(TerminalSize {
            cols,
            rows,
            width_px: cols * 8, // 假设字符宽度为8像素
            height_px: rows * 16, // 假设字符高度为16像素
        })
}